home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Workspace / MonsterShelf / Source / IconView.m < prev    next >
Encoding:
Text File  |  1993-09-05  |  6.8 KB  |  335 lines

  1. #import "IconView.h"
  2. #import "ShelfView.h"
  3. #import "Controller.h"
  4.  
  5. #import <appkit/workspaceRequest.h>
  6. #import <appkit/appkit.h>
  7. #import <mach/mach.h>
  8. #import <bsd/sys/file.h>
  9.  
  10.  
  11. #define    IMAGE_OFFSET    2
  12.  
  13.  
  14. @implementation NXImage(UsefulMethod)
  15. - (NXSize) scaleToFitInside:(NXSize) size max:(NXSize) maxSize
  16. {
  17.     NXSize    imageSize;
  18.     float    scale;
  19.  
  20.     [self getSize:&imageSize];
  21.  
  22.     scale = MIN(size.width/imageSize.width, size.height/imageSize.height);
  23.  
  24.     size.width = scale * imageSize.width;
  25.     size.height = scale * imageSize.height;
  26.     if (size.width > maxSize.width)
  27.         size.width = maxSize.width;
  28.     if (size.height > maxSize.height)
  29.         size.height = maxSize.height;
  30.  
  31.     [self setSize:&size];
  32.     return size;
  33. }
  34. @end
  35.  
  36.  
  37. @implementation IconView : View
  38.  
  39. static id    scaledHilite;
  40.  
  41. + initialize
  42. {
  43.     scaledHilite = nil;
  44.     [self resetCachedImages];
  45.     return self;
  46. }
  47.  
  48. + resetCachedImages
  49. {
  50.     [scaledHilite free];
  51.     scaledHilite = [[NXImage findImageNamed:"hilite"]
  52.                 copyFromZone:[self zone]];
  53.     return self;
  54. }
  55.  
  56. + hilite
  57. {
  58.     return scaledHilite;
  59. }
  60.  
  61.  
  62. /*
  63.  *  Create a copy of an IconView (or an IconView subclass).  Note that this
  64.  *  method cheats by potentially changing the class of the copied image.
  65.  */
  66. + copyIconView:aView
  67. {
  68.     NXRect        aFrame;
  69.     void        *oldData;
  70.     unsigned int    len;
  71.     
  72.     [aView getFrame:&aFrame];
  73.     [aView getData:&oldData andLength:&len];
  74.  
  75.     return [[self allocFromZone:[aView zone]] initFrame:&aFrame
  76.                 image:[[aView image] copy]
  77.             data:oldData andLength:len
  78.             useSize:YES];
  79. }
  80.  
  81.  
  82. /*
  83.  *  Initialize a new IconView.  The only thing sneaky about this
  84.  *  method is that we may interpret the size of the frame as the
  85.  *  max size for the frame.
  86.  */
  87. - initFrame:(const NXRect *) newFrame
  88.         image:anImage
  89.         data:(const void *) someData
  90.         andLength:(unsigned int) newLength
  91.         useSize:(BOOL) sizeValid
  92. {
  93.     NXSize    imageSize = {48, 48};
  94.  
  95.     selected = NO;
  96.     ghost = NO;
  97.   
  98.     hilite = [IconView hilite];
  99.     [hilite getSize:&hiliteMax];
  100.  
  101.     image = anImage;
  102.     imageMax = imageSize;
  103.  
  104.     /*
  105.      *  Copy the data, with null termination if it's not already.
  106.      */
  107.     if (newLength > 0 && *((char *)someData + newLength - 1))
  108.         length = newLength + 1;
  109.     else
  110.     length = newLength;
  111.  
  112.     data = NXZoneMalloc([self zone], length);
  113.     bcopy(someData, data, length);
  114.     *((char *)data + length - 1) = '\0';
  115.  
  116.     /*
  117.      *  Allocate a cell, and slam the filename into it.  Make sure to use
  118.      *  only the last component of the path.
  119.      */
  120.     titleCell = [[TextFieldCell allocFromZone:[self zone]] init];
  121.     [titleCell setAlignment:NX_CENTERED];
  122.     [titleCell setBackgroundTransparent:YES];
  123.  
  124.     if (rindex(data, '/'))
  125.     [titleCell setStringValue:rindex(data, '/') + 1];
  126.     else
  127.     [titleCell setStringValue:data];
  128.  
  129.     /*
  130.      *  If there's no frame, make one that's the right size to hold
  131.      *  everything.
  132.      */
  133.     if (!sizeValid) {
  134.         NXSize    titleSize;
  135.     NXRect    aRect = { {0,0}, {0,0} };
  136.  
  137.     [hilite getSize:&imageSize];
  138.     [titleCell calcCellSize:&titleSize];
  139.  
  140.         if (newFrame)
  141.         aRect.origin = newFrame->origin;
  142.     aRect.size.height = imageSize.height + titleSize.height;
  143.     aRect.size.width = MAX(titleSize.width, imageSize.width);
  144.     [super initFrame:&aRect];
  145.     }
  146.     else
  147.     [super initFrame:newFrame];
  148.  
  149.     [self setImageSize];
  150.  
  151.     return self;
  152. }
  153.  
  154.  
  155. - initFromDragContext:(id <NXDraggingInfo>)context andSize:(NXSize *) aSize
  156. {
  157.     NXImage        *copiedImage = [context draggedImageCopy];
  158.     Pasteboard        *pb = [Pasteboard newName:NXDragPboard];
  159.     char        *pbData;
  160.     NXRect        aRect = { {0,0}, {0,0} };
  161.     NXRect        *rectPtr = NULL;
  162.     unsigned int    len;
  163.  
  164.     [pb readType:NXFilenamePboardType data:&pbData length:&len];
  165.  
  166.     if (aSize != NULL) {
  167.         rectPtr = &aRect;
  168.     aRect.size = *aSize;
  169.     }
  170.  
  171.     [self initFrame:rectPtr image:copiedImage data:pbData andLength:len+1
  172.             useSize:aSize != NULL];
  173.  
  174.     return self;
  175. }
  176.  
  177.  
  178. - free
  179. {
  180.     free(data);
  181.     [image free];
  182.     [titleCell free];
  183.     return [super free];
  184. }
  185.  
  186.  
  187. - (NXCoord) cellHeight
  188. {
  189.     NXSize    cellSize;
  190.     [titleCell calcCellSize:&cellSize];
  191.     return cellSize.height;
  192. }
  193.  
  194.  
  195. - getImagePoint:(NXPoint *) imageLoc andHilitePoint:(NXPoint *) hiliteLoc
  196. {
  197.     NXCoord    cellHeight;
  198.     NXSize    hiliteSize, imageSize;
  199.  
  200.     cellHeight = [self cellHeight];
  201.  
  202.     /*
  203.      *  Determine where the image and cell go in the new view.
  204.      */
  205.     if (imageLoc) {
  206.     [image getSize:&imageSize];
  207.     imageLoc->x = (bounds.size.width - imageSize.width) / 2;
  208.     imageLoc->y = cellHeight + 
  209.             (bounds.size.height - imageSize.height - cellHeight) / 2;
  210.     }
  211.     
  212.     if (hiliteLoc) {
  213.     [hilite getSize:&hiliteSize];
  214.     hiliteLoc->x = (bounds.size.width - hiliteSize.width) / 2;
  215.     hiliteLoc->y = imageLoc->y -
  216.             (hiliteSize.height - imageSize.height) / 2;
  217.     }
  218.  
  219.     return self;
  220. }
  221.  
  222.  
  223. - (void) setImageSize
  224. {
  225.     NXSize    imageSize;
  226.  
  227.     [image setScalable:YES];
  228.     [hilite setScalable:YES];
  229.  
  230.     imageSize = bounds.size;
  231.     imageSize.height -= [self cellHeight];
  232.  
  233.     imageSize = [hilite scaleToFitInside:imageSize max:hiliteMax];
  234.     (void) [image scaleToFitInside:imageSize max:imageMax];
  235. }
  236.  
  237.  
  238. - sizeTo:(NXCoord) width :(NXCoord) height
  239. {
  240.     [super sizeTo:width :height];
  241.     [self setImageSize];
  242.     return self;
  243. }
  244.  
  245.  
  246. - drawSelf:(const NXRect *) rects :(int) rectCount
  247. {
  248.     NXPoint    imagePoint, hilitePoint;
  249.     NXRect    cellRect;
  250.  
  251.     [self getImagePoint:&imagePoint andHilitePoint:&hilitePoint];
  252.  
  253.     if (NXBrightnessComponent([superview backgroundColor]) < NX_DKGRAY + 0.01)
  254.     [titleCell setTextGray:[self isGhost] ? NX_LTGRAY : NX_WHITE];
  255.     else
  256.     [titleCell setTextGray:[self isGhost] ? NX_DKGRAY : NX_BLACK];
  257.  
  258.     NXSetRect(&cellRect, 0, hilitePoint.y - [self cellHeight],
  259.                     bounds.size.width, [self cellHeight]);
  260.     [titleCell drawInside:&cellRect inView:self];
  261.  
  262.     if ([self isGhost]) {
  263.         id tempImage = [[NXImage alloc] initSize:&bounds.size];
  264.     if ([tempImage lockFocus]) {
  265.          PSsetalpha(0);
  266.          NXRectFill(&bounds);
  267.          [image dissolve:0.6666 toPoint:&imagePoint];
  268.          [tempImage unlockFocus];
  269.     }
  270.     [tempImage composite:NX_SOVER toPoint:&bounds.origin];
  271.     [tempImage free];
  272.     }
  273.     else {
  274.     if ([self state])
  275.         [hilite composite:NX_SOVER toPoint:&hilitePoint];
  276.     else {
  277.         NXRect    aRect;
  278.         [hilite getSize:&aRect.size];
  279.         aRect.origin = hilitePoint;
  280.         [self convertRect:&aRect toView:superview];
  281.         [superview lockFocus];
  282.         [superview drawSelf:&aRect :1];
  283.         [superview unlockFocus];
  284.     }
  285.     [image composite:NX_SOVER toPoint:&imagePoint];
  286.     }
  287.     
  288.     return self;
  289. }
  290.  
  291.  
  292. - image
  293. {
  294.     return image;
  295. }
  296.  
  297.  
  298. - getData:(void **) aPtr andLength:(unsigned int *) aLength
  299. {
  300.     *aPtr = data;
  301.     *aLength = length;
  302.     return self;
  303. }
  304.  
  305.  
  306. - setGhost:(BOOL) newGhost
  307. {
  308.     ghost = newGhost;
  309.     return self;
  310. }
  311.  
  312.  
  313. - (BOOL) isGhost
  314. {
  315.     return ghost;
  316. }
  317.  
  318.  
  319. - (int) state
  320. {
  321.     return selected;
  322. }
  323.  
  324.  
  325. - setState:(int) flag
  326. {
  327.     if (flag ^ selected) {
  328.     selected = flag ? YES : NO;
  329.         [self display];
  330.     }
  331.     return self;
  332. }
  333.  
  334. @end
  335.